package com.lechi.iot.netty.handle;

import com.lechi.iot.netty.message.TcpInMessage;
import com.lechi.iot.netty.message.TcpMessage;
import com.lechi.web.framework.util.GuavaCacheUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import lombok.extern.slf4j.Slf4j;

import java.net.InetSocketAddress;
import java.util.List;
import java.util.Objects;

/**
 * 自定义解码器，将字节流解码为 Java 对象。通常用于接收到数据后进行解码。
 * ，不是所有的handler都可以添加这个注解的，被修饰的handler必须是无状态的，或者说，线程安全的。例如，如果解码器继承自ByteToMessageDecoder，就不能添加该注解。因为ByteToMessageDecoder类里含有成员变量。
 */
@Slf4j
public class TcpMessageDecoder extends ByteToMessageDecoder {

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
        String hostName = getHostName(ctx);
        byte[] array = new byte[in.readableBytes()];
        in.readBytes(array);
        String inputDeviceSN = new String(array).trim();

        if (Objects.nonNull(GuavaCacheUtil.getBiDeviceSnAndIPMap().get(inputDeviceSN))) {
            log.info("接收到设备序列号：{} 存在性校验通过, 设备地址：{}", inputDeviceSN, hostName);
            TcpMessage msg = new TcpInMessage(hostName, inputDeviceSN);
            out.add(msg);
            return;
        }
        TcpMessage msg = new TcpInMessage(hostName, array);
        out.add(msg);
    }

    public String getHostName(ChannelHandlerContext ctx) {
        InetSocketAddress inetSocketAddress = (InetSocketAddress) ctx.channel().remoteAddress();
        return inetSocketAddress.getHostString();
    }

}
